package com.sunxboy.platform.option;

import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.util.Assert;

public class CommandLineArgumentProcessor {
    private static final Logger LOG = Logger.getLogger(CommandLineArgumentProcessor.class);
    private final CommandLineOptions commandLineOptions = new CommandLineOptions();
    private final String[] remainingArgs;

    public CommandLineArgumentProcessor(final String[] args) {
        this.remainingArgs = processArguments(args);
    }

    public String[] copyOfRange(String[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        String[] copy = new String[newLength];
        System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));
        return copy;
    }

    public String[] processArguments(String[] args) {

        List<String> unhandledArgs = new LinkedList<String>();
        for (int argIndex = 0; argIndex < args.length; argIndex++) {
            String argument = args[argIndex];
            if (argument.equals("--")) {
                return copyOfRange(args, argIndex, args.length);
            }

            if (argument.startsWith("--core:")) {
                Assert.isTrue((argIndex + 1) < args.length, "Options " + argument + " requires a value parameter that is missing");

                final String value = args[++argIndex];
                Options option = Options.toOption(argument);
                if (option != null) {
                    option.processValue(commandLineOptions, value);
                }
                else {
                    LOG.warn(String.format("Option %s and value %s are not handled", option, value));
                }

            }
            else {
                unhandledArgs.add(args[argIndex]);
            }
        }

        return unhandledArgs.toArray(new String[] {});
    }

    public String[] getArguments() {
        return remainingArgs;
    }

    public CommandLineOptions getOptions() {
        return commandLineOptions;
    }
}
